#include <iostream>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>

int main() {
    const char* file_path = "log.txt";
    
    // 1. 打开文件
    int fd = open(file_path, O_RDWR);
    if (fd == -1) {
        std::cerr << "无法打开文件: " << strerror(errno) << std::endl;
        return 1;
    }
    
    // 2. 获取文件大小
    struct stat sb; //文件属性
    if (fstat(fd, &sb) == -1) {
        std::cerr << "无法获取文件状态: " << strerror(errno) << std::endl;
        close(fd);
        return 1;
    }
    //off_t long int
    off_t file_size = sb.st_size;
    std::cout << "文件大小: " << file_size << " 字节" << std::endl;
    
    // 3. 映射文件到内存
    void* mapped = mmap(nullptr, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (mapped == MAP_FAILED) {
        std::cerr << "mmap失败: " << strerror(errno) << std::endl;
        close(fd);
        return 1;
    }
    
    // 4. 现在可以通过指针访问文件内容
    char* file_data = static_cast<char*>(mapped);
    printf("%s\n",file_data);
    // std::cout << "文件内容前100字节: " << std::endl;
    // std::cout.write(file_data, std::min(static_cast<off_t>(100), file_size));
    // std::cout << std::endl;
    
    // 5. 可以修改文件内容（因为我们用了PROT_WRITE）
    // 例如，修改第一个字符（如果有内容的话）
    if (file_size > 0) {
        file_data[0] = 'M';
        std::cout << "已修改第一个字符" << std::endl;
        
        // 由于使用了MAP_SHARED，修改会自动同步到文件
        // 但为了确保立即同步，可以调用msync
        if (msync(mapped, file_size, MS_SYNC) == -1) {
            std::cerr << "msync失败: " << strerror(errno) << std::endl;
        }
    }
    
    // 6. 解除映射并关闭文件
    if (munmap(mapped, file_size) == -1) {
        std::cerr << "munmap失败: " << strerror(errno) << std::endl;
    }
    
    close(fd);
    
    return 0;
}